﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.ClientEngine;
using SuperSocket.ProtoBase;
using Mode;
using Newtonsoft.Json;
using System.Net;
using System.ComponentModel;
using System.Threading;

namespace EasyClientPlus
{
    public class ClientPlus
    {
        public delegate void Received(PackageEventArgs<BinaryPackageInfo<short>> Data);
        public event Received DataReceived;  //接收服务器返回数据
        public delegate void ConnectServer(object sender, EventArgs e);
        public event ConnectServer Connect;  //连接服务器事件

        //关闭事件做为重连用
     //   public delegate void CloseServer(object sender, EventArgs e);
    //    public event CloseServer Close;  //关闭服务器事件

        public delegate void ReConnectServer();
        public event ReConnectServer ReCon;  //重连事件

     //   重连接可以不用，在连接事件就可以更新界面
    //    public delegate void ReConnectStart();
     //   public event ReConnectStart ReConStrar;  //重连完成

        private EasyClient<BinaryPackageInfo<Int16>> Client;
        public string _ip { get; set; }//服务器地址
        public int _port { get; set; }//服务器端口
        public string _UserName { get; set; }//登录用户名
        public string _Password { get; set; }//登录密码
        public bool _Connected { get; set; }//是否已连接

        private IPAddress[] ips;//ip地址字段


        private BackgroundWorker _worker = new BackgroundWorker(); // 监听线程 定时监听服务器状态
    //    private BackgroundWorker _fileworker = new BackgroundWorker();  //发送文件专用

        
        /// <summary>
        /// 初始化客户端
        /// </summary>
        public bool InitClient()
        {
            ips = Dns.GetHostAddresses(_ip);
            Client = new EasyClient<BinaryPackageInfo<short>>();
            Client.Initialize(new FixedHeaderReceiveFilter());
            Client.Connected += Client_Connected;
            Client.NewPackageReceived += Client_NewPackageReceived;
            Client.Closed += Client_Closed;
            if (Client.ConnectAsync(new IPEndPoint(ips[0], _port)).Result == false)
            {
                return false;
            };
            _worker.WorkerSupportsCancellation = true;//保证被T后不自动重连接
            _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
            _worker.RunWorkerAsync();
            return true;
        }

        private void Client_Closed(object sender, EventArgs e)
        {

            //   if (Close != null)
            //  {
            //      this.Close(sender, e);
            //  }

            if (ReCon!=null)
            {
                ReCon();
            }
        }

        private void Client_NewPackageReceived(object sender, PackageEventArgs<BinaryPackageInfo<short>> e)
        {
            if (DataReceived != null)
            {
                this.DataReceived(e);
            }
        }

        private void Client_Connected(object sender, EventArgs e)
        {
            if (Connect != null)
            {
                this.Connect(sender, e);
            }
        }

        /// <summary>
        /// 通信状态检测线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _worker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (_worker.CancellationPending == true)
                {
                    return;
                }
                try
                {
                    CheckLive();
                }
                catch (Exception errException)
                {
                    // 心跳异常记录 
                }
                Thread.Sleep(1000);
            }
        }
      
        public void SendData(int infotype, byte[] data)
        {
            MessageByte msbyte = new MessageByte();
            msbyte.infoType = infotype;
            msbyte.MsgByte = data;

            byte[] info = SerializationHelpers.ObjectToByte(msbyte);
            var infoOut = new ArraySegment<byte>(BitConverter.GetBytes(info.Length).Concat(info).ToArray());
            Client.Send(infoOut);
        }

        /// <summary>
        /// 心跳检测
        /// </summary>
        private void CheckLive()
        {
            if (HeartBeat())
            {
                _Connected = true;
            }
            else
            {
                _Connected = false;
                if (ReConnect(ips, _port))
                    Login(); //登陆
            }
        }

        private bool ReConnect(IPAddress[] ip, int Port)
        {
            if (_worker.CancellationPending == true)
            {
                return false; 
            }

            if (Client.ConnectAsync(new IPEndPoint(ip[0], Port)).Result == false)
            {
                return false;
            }
            return true;         
        }
        /// <summary>
        /// 心跳检测
        /// </summary>
        /// <returns></returns>
        public bool HeartBeat()
        {   
            try
            {
                byte[] info = Encoding.UTF8.GetBytes("HB");
                SendData(InformationTypes.HeartBeat, info);
            }
            catch// (Exception E)
            {
                //写入日志
                return false;
            }
            return true;
        }

        /// <summary>
        /// 登录服务器
        /// </summary>
        private void Login()
        {
            
            #region 获取登录用户列表

            //    byte[] info = SerializationHelpers.ObjectToByte(ms);
            //   SendData(InformationTypes.Login, info);
            #endregion
        }



    }
}
